//
//  GameObjectModel.cpp
//  Editor
//
//  Created by Jeppe Nielsen on 11/10/14.
//  Copyright (c) 2014 Jeppe Nielsen. All rights reserved.
//

#include "GameObjectModel.hpp"
#include <QtCore/QMimeData>
#include <iostream>
#include "GameObject.hpp"
#include "GameWorld.hpp"
#include "SerializedComponent.hpp"

using namespace Qt;

GameObjectModel::GameObjectModel(GameObject* gameObject, QObject *parent) : QAbstractItemModel(parent) {
    this->gameObject = gameObject;
    gameObject->Serialize(&serializedObject);
}

GameObjectModel::~GameObjectModel() { }

void GameObjectModel::Deserialize() {
    gameObject->Deserialize(&serializedObject);
}

int GameObjectModel::columnCount(const QModelIndex &parent) const {
    return 2;
}

QVariant GameObjectModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();
    
   ISerializedProperty* property =static_cast<ISerializedProperty*>(index.internalPointer());
    
    if (index.column() == 0) {
        return QString(property->name.c_str());
    } else {
        if (!property->GetEditor()) {
            return "";
        }
        QVariant value;
        property->GetEditor()->GetValue(property, &value);
        return value;
    }
}

Qt::ItemFlags GameObjectModel::flags(const QModelIndex &index) const {

    Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
    
    if (index.column() == 0) {
        return defaultFlags;
    }

     if (index.isValid())
         return Qt::ItemIsEditable | Qt::ItemIsSelectable | defaultFlags;
     else
         return Qt::ItemIsSelectable | defaultFlags;
}

QVariant GameObjectModel::headerData(int section, Qt::Orientation orientation, int role) const {
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return section == 0 ? "Property" : "Value";

    return QVariant();
}

QModelIndex GameObjectModel::index(int row, int column, const QModelIndex &parent) const {
    if (!gameObject) {
        return QModelIndex();
    }

    if (!hasIndex(row, column, parent))
        return QModelIndex();
    
    
    if (!parent.isValid()) {
        return createIndex(row, column, (void*)&serializedObject);
    } else {
        ISerializedProperty* property = static_cast<ISerializedProperty*>(parent.internalPointer());
        return createIndex(row, column, property->GetChildren()[row]);
    }
}

QModelIndex GameObjectModel::parent(const QModelIndex &index) const
{
    
    if (!index.isValid() || !gameObject)
        return QModelIndex();
    
    ISerializedProperty* property = static_cast<ISerializedProperty*>(index.internalPointer());
    
    if (!property->GetParent()) {
        return QModelIndex();
    } else {
        ISerializedProperty* parent = property->GetParent();
        for (int i=0; i<parent->GetChildren().size(); i++) {
            if (parent->GetChildren()[i] == property) {
                return createIndex(i, 0, parent);
            }
        }
    }
    return QModelIndex();
}

int GameObjectModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column()>0 || !gameObject) {
        return 0;
    }

    if (!parent.isValid()) {
        return 1;
    } else {
        ISerializedProperty* component = static_cast<ISerializedProperty*>(parent.internalPointer());
        return (int)component->GetChildren().size();
    }
}


Qt::DropActions GameObjectModel::supportedDropActions() const {
     return Qt::MoveAction; //Qt::CopyAction | Qt::MoveAction;
}

bool GameObjectModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) {
    return false;
}

QMimeData* GameObjectModel::mimeData(const QModelIndexList &indexes) const
 {
     return 0;
 }





